﻿using Microsoft.Extensions.DependencyModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace ThresholdAssistant.Tools
{
    /// <summary>
    /// 程序集工具类
    /// </summary>
    public class AssemblyUtil
    {
        /// <summary>
        /// 获取文件名称
        /// </summary>
        /// <param name="baseType"></param>
        /// <returns></returns>
        public static Assembly[] GetAssemblyList(Type baseType)
        {
            Assembly[] assemblyList = new Assembly[] { };
            try
            {
                var libTypeList = new List<string>() { "project", "package" };
                var fileNameList = DependencyContext.Default.CompileLibraries
                    .Where(lib => libTypeList.Contains(lib.Type)
                    && !lib.Name.StartsWith("Microsoft.", StringComparison.CurrentCultureIgnoreCase)
                    && !lib.Name.StartsWith("System.", StringComparison.CurrentCultureIgnoreCase)
                    && !lib.Name.StartsWith("runtime.", StringComparison.CurrentCultureIgnoreCase))
                    .Select(lib => lib.Name);

                IEnumerable<Assembly> allAssemblyList = fileNameList.Select(assemblyName => GetAssembly(assemblyName));
                assemblyList = allAssemblyList.Where(assembly => CheckIsAssignableFrom(assembly, baseType)).ToArray();
            }
            catch (Exception)
            {
            }
            return assemblyList;
        }

        /// <summary>
        /// 检查是否某名命空间下面的类是否包含有莫格Type的子类
        /// </summary>
        /// <param name="assembly"></param>
        /// <param name="baseType"></param>
        /// <returns></returns>
        private static bool CheckIsAssignableFrom(Assembly assembly, Type baseType)
        {
            bool isSuccess = false;
            try
            {
                if (assembly == null)
                    return isSuccess;

                Type[] types = assembly.GetTypes();
                isSuccess = types.Any(type => baseType.IsAssignableFrom(type) && type != baseType);
            }
            catch (Exception)
            {
            }
            return isSuccess;
        }

        /// <summary>
        /// 获取程序集
        /// </summary>
        /// <param name="assemblyName"></param>
        private static Assembly GetAssembly(string assemblyName)
        {
            Assembly assembly = null;
            try
            {
                assembly = Assembly.Load(assemblyName);
            }
            catch (Exception)
            {

            }
            return assembly;
        }
    }
}